package org.star.dolphin.utils;

import com.alibaba.fastjson.JSON;
import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;
import org.star.dolphin.domain.TokenPlayload;
import org.apache.commons.lang3.StringUtils;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;

public class TokenUtil {

    private String JWT_ISS;

    private String SECRET;

    public TokenUtil(String jwt_iss, String secret) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        this.JWT_ISS = SecurityUtil.encoder(jwt_iss, "UTF-8");
        this.SECRET = SecurityUtil.encoder(secret, "UTF-8");
    }

    /**
     * 创建token
     *
     * @param tokenPlayload
     * @return
     * @throws JOSEException
     */
    public String createToken(TokenPlayload tokenPlayload) throws JOSEException {
        //设置签发机构
        tokenPlayload.setIss(JWT_ISS);
        //jwt header
        JWSHeader jwsHeader = new JWSHeader(JWSAlgorithm.HS256);
        //jwt payload
        Payload payload = new Payload(JSON.toJSONString(tokenPlayload));
        //将头部和载荷结合在一起
        JWSObject jwsObject = new JWSObject(jwsHeader, payload);
        //secret秘钥 （32-byte）
        JWSSigner jwsSigner = new MACSigner(SECRET.getBytes());
        //签名
        jwsObject.sign(jwsSigner);
        //生成token
        return jwsObject.serialize();
    }

    /**
     * 验证token
     *
     * @param token
     * @return
     * @throws ParseException
     * @throws JOSEException
     */
    public TokenPlayload validateToken(String token) throws ParseException, JOSEException {
        //解析token
        JWSObject jwsObject = JWSObject.parse(token);
        //获取到载荷
        Payload payload = jwsObject.getPayload();
        //建立一个解锁密匙
        JWSVerifier jwsVerifier = new MACVerifier(SECRET.getBytes());

        //判断token
        if (jwsObject.verify(jwsVerifier)) {

            TokenPlayload tokenPlayload = JSON.parseObject(payload.toString(), TokenPlayload.class);

            //判断发行方是否一致
            if (!StringUtils.equals(tokenPlayload.getIss(), JWT_ISS)) {
                return null;
            } else {
                return tokenPlayload;
            }
        } else {
            return null;
        }
    }
}
